﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using QLTT.Models;
using QLTT.Commands;
using System.Windows.Input;
using System.Windows.Data;
using System.Windows;


namespace QLTT.ViewModels
{
    public enum AbsenceDate
    {
        AllDate,
        ExactDate,
        AnyDate
    };
    public class EnumBooleanConverter : IValueConverter
    {
        #region IValueConverter Members
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            string parameterString = parameter as string;
            if (parameterString == null)
                return DependencyProperty.UnsetValue;

            if (Enum.IsDefined(value.GetType(), value) == false)
                return DependencyProperty.UnsetValue;

            object parameterValue = Enum.Parse(value.GetType(), parameterString);

            return parameterValue.Equals(value);
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            string parameterString = parameter as string;
            if (parameterString == null)
                return DependencyProperty.UnsetValue;

            return Enum.Parse(targetType, parameterString);
        }
        #endregion
    }
    class AllAbsenceViewModel : WorkspaceViewModel
    {
        private ObservableCollection<AbsenceViewModel> _lstAbsenceViewModel;
        AbsenceDate _dateMode;
        private icanDataContext _dataContext;
        private DelegateCommand _findCommand;
        private DelegateCommand _addCommand;
        private DelegateCommand _deleteCommand;
        private IQueryable<AbsenceViewModel> _query;
        private long _rClass;
       public AllAbsenceViewModel(icanDataContext dataContext)
        {
            _lstAbsenceViewModel = new ObservableCollection<AbsenceViewModel>();
            _dataContext = dataContext;
            base.DisplayName = Properties.Resources.Base_DisplayName_AllAbsence;

        }
        public AllAbsenceViewModel(icanDataContext dataContext, bool isGetAll)
        {
            _lstAbsenceViewModel = new ObservableCollection<AbsenceViewModel>();
            _dataContext = dataContext;
            if (isGetAll)
            {
                this.Class = _dataContext.Classes.Where(oClass => oClass.EndDate >= DateTime.Today).OrderByDescending(oClass => oClass.StartDate).Select(oClass => oClass.ID).FirstOrDefault();
                this.Date = DateTime.Today;
                this.DateMode = AbsenceDate.AnyDate;
                _query = from absence in _dataContext.Absences where (absence.StudentClass1.Class == this.Class)  select new AbsenceViewModel(_dataContext, absence);
                
                this.NumRow = _query.Count();
                this.CurPage = 1;
                this.UpdateList();
            }
            base.DisplayName = Properties.Resources.Base_DisplayName_AllAbsence;
        }
        public AllAbsenceViewModel(icanDataContext dataContext, Student oStudent)
        {
            _lstAbsenceViewModel = new ObservableCollection<AbsenceViewModel>();
            _dataContext = dataContext;
            this.Date = DateTime.Today;
            this.DateMode = AbsenceDate.AnyDate;
            long lClassId = _dataContext.StudentClasses.Where(o => o.Student == oStudent.ID).Select(o => o.Class).FirstOrDefault();
            if (lClassId > 0)
            {
                this.Class = lClassId;
                this.Student = oStudent.ID;
                base.OnPropertyChanged("Student");
                Find();
            }
            base.DisplayName = Properties.Resources.Base_DisplayName_AllAbsence;
        }
        public AbsenceDate DateMode
        {
            get { return _dateMode; }
            set
            {
                if (_dateMode == value)
                    return;
                _dateMode = value;
                base.OnPropertyChanged("DateMode");
            }
        }
        public DateTime Date { get; set; }
        public long Student { get; set; }
        public long Class {
            get
            {
                return _rClass;
            }
            set
            {
                if (_rClass == value) return;
                _rClass = value;
                base.OnPropertyChanged("Class");
                base.OnPropertyChanged("Students");
                this.Student = 0;
                base.OnPropertyChanged("Student");
            }
        }
        public List<ClassViewModel> Classes
        {
            get
            {
                return _dataContext.Classes.Where(oClass => oClass.EndDate >= DateTime.Today).Select(oClass => new ClassViewModel(_dataContext, oClass)).ToList();
            }
        }
        public List<StudentViewModel> Students
        {
            get
            {
                if (this.Class == 0)
                    return new List<StudentViewModel>();
                List<long> lstIDs = _dataContext.StudentClasses.Where(sc => sc.Class == this.Class).Select(sc => sc.Student).ToList();
                List<StudentViewModel> lstSVM = _dataContext.Students.Where(s => lstIDs.Contains(s.ID)).Select(s => new StudentViewModel(_dataContext, s)).ToList();
                StudentViewModel sVM = new StudentViewModel(_dataContext);
                sVM.Name = Properties.Resources.Combo_AllAbsence_Student_Default;
                lstSVM.Insert(0, sVM);
                return lstSVM;
            }
        }
        public ObservableCollection<AbsenceViewModel> AllAbsences
        {
            get { return _lstAbsenceViewModel; }
            set {
                _lstAbsenceViewModel = value;
                base.OnPropertyChanged("AllAbsences");
            }
        }
        public ICommand FindCommand
        {
            get
            {
                if (_findCommand == null)
                {
                    _findCommand = new DelegateCommand(Find);
                }
                return _findCommand;
            }
        }
        public ICommand AddCommand
        {
            get
            {
                if (_addCommand == null)
                {
                    _addCommand = new DelegateCommand(AddAbsence);
                }
                return _addCommand;
            }
        }
        public ICommand DeleteCommand
        {
            get
            {
                if (_deleteCommand == null)
                {
                    _deleteCommand = new DelegateCommand(DeleteAbsence, CanDeleteAbsence);
                }
                return _deleteCommand;
            }
        }
        
        
        public void Find()
        {
            IQueryable<Absence> myQuery = _dataContext.Absences;
            if (this.Class > 0)
                myQuery = myQuery.Where<Absence>(absence => absence.StudentClass1.Class==this.Class);
            //Add more Where Conditions here
            if(this.DateMode == AbsenceDate.ExactDate)
                myQuery = myQuery.Where<Absence>(absence => absence.Date==this.Date);
            if (this.Student > 0)
                myQuery = myQuery.Where<Absence>(absence => absence.StudentClass1.Student == this.Student);
            //Order
            myQuery = myQuery.OrderByDescending(absence => absence.Date);
            //Select
            _query = myQuery.Select(absence => new AbsenceViewModel(_dataContext, absence));
            this.NumRow = _query.Count();
            //Reset to page 0
            this.CurPage = 1;
            this.UpdateList();
        }
        
        public void AddAbsence()
        {
            AbsenceViewModel ws = new AbsenceViewModel(_dataContext);
            Mediator.NotifyColleagues<WorkspaceViewModel>(Messages.WorkspaceAdd, ws);
        }
        
        private void DeleteAbsence()
        {
            foreach (AbsenceViewModel tvm in AllAbsences)
            {
                if (tvm.IsSelected)
                {
                    tvm.Delete();
                }
            }
            this.NumRow = _query.Count();
            this.UpdateList();

        }
        private bool CanDeleteAbsence()
        {
            return AllAbsences.Count(a => a.IsSelected == true) > 0;
        }
        [MediatorLib.MediatorMessageSink(Messages.ListAbsenceUpdated, ParameterType = typeof(Absence))]
        public void UpdateListAbsence(Absence absence)
        {
            this.NumRow = _query.Count();
            this.UpdateList();
        }

        public override void UpdateList()
        {
            List<AbsenceViewModel> lstAbsences = _query.Skip((this.CurPage - 1) * this.RowsPerPage).Take(this.RowsPerPage).ToList();
            AllAbsences = new ObservableCollection<AbsenceViewModel>(lstAbsences);
            base.UpdateList();
        }
    }
}

